using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace GenerativeAgents.Core
{
    /// <summary>
    /// 感知系统
    /// 负责从环境中感知事件并进行初步处理
    /// </summary>
    public class PerceptionSystem : MonoBehaviour
    {
        [Header("感知配置")]
        [SerializeField] private float visionRadius = 8f;
        [SerializeField] private int attentionBandwidth = 3;
        [SerializeField] private LayerMask perceptionLayers = -1;
        [SerializeField] private float perceptionInterval = 1f;
        [SerializeField] private float eventRetentionTime = 300f; // 5分钟
        
        [Header("调试信息")]
        [SerializeField] private bool enableDebugVisualization = true;
        [SerializeField] private bool enablePerceptionLogging = false;
        
        // 组件引用
        private MemorySystem memorySystem;
        private EnvironmentScanner scanner;
        private EventProcessor processor;
        private IEmbeddingEngine embeddingEngine;
        private ILanguageModel languageModel;
        
        // 感知状态
        private HashSet<string> recentEventIds;
        private Dictionary<string, DateTime> eventTimeStamps;
        private List<AgentEvent> currentPerceptions;
        private float lastPerceptionTime;
        
        // 事件
        public event System.Action<AgentEvent> OnEventPerceived;
        public event System.Action<List<AgentEvent>> OnPerceptionCycle;
        
        private void Awake()
        {
            InitializePerceptionSystem();
        }
        
        private void Start()
        {
            StartPerceptionLoop();
        }
        
        private void InitializePerceptionSystem()
        {
            // 获取组件引用
            memorySystem = GetComponent<MemorySystem>();
            scanner = GetComponent<EnvironmentScanner>();
            processor = GetComponent<EventProcessor>();
            embeddingEngine = GetComponent<IEmbeddingEngine>();
            languageModel = GetComponent<ILanguageModel>();
            
            // 初始化数据结构
            recentEventIds = new HashSet<string>();
            eventTimeStamps = new Dictionary<string, DateTime>();
            currentPerceptions = new List<AgentEvent>();
            
            // 如果组件不存在，创建默认组件
            if (scanner == null)
            {
                scanner = gameObject.AddComponent<EnvironmentScanner>();
            }
            
            if (processor == null)
            {
                processor = gameObject.AddComponent<EventProcessor>();
            }
        }
        
        private void Update()
        {
            // 定期执行感知循环
            if (Time.time - lastPerceptionTime >= perceptionInterval)
            {
                PerformPerceptionCycle();
                lastPerceptionTime = Time.time;
            }
            
            // 清理过期事件
            CleanupExpiredEvents();
        }
        
        /// <summary>
        /// 执行完整的感知循环
        /// </summary>
        public List<AgentEvent> PerformPerceptionCycle()
        {
            try
            {
                // 1. 扫描环境
                var perceivedObjects = scanner.ScanEnvironment(transform.position, visionRadius, perceptionLayers);
                
                // 2. 提取原始事件
                var rawEvents = scanner.ExtractRawEvents(perceivedObjects);
                
                // 3. 过滤新事件
                var newEvents = FilterNewEvents(rawEvents);
                
                // 4. 限制注意力带宽
                var prioritizedEvents = LimitAttentionBandwidth(newEvents);
                
                // 5. 处理事件
                var processedEvents = ProcessEvents(prioritizedEvents);
                
                // 6. 存储到记忆系统
                StoreEventsToMemory(processedEvents);
                
                // 7. 更新感知状态
                UpdatePerceptionState(processedEvents);
                
                // 8. 触发事件
                OnPerceptionCycle?.Invoke(processedEvents);
                
                if (enablePerceptionLogging)
                {
                    Debug.Log($"[PerceptionSystem] Perceived {processedEvents.Count} events from {rawEvents.Count} raw events");
                }
                
                return processedEvents;
            }
            catch (Exception ex)
            {
                Debug.LogError($"[PerceptionSystem] Error in perception cycle: {ex.Message}");
                return new List<AgentEvent>();
            }
        }
        
        /// <summary>
        /// 过滤新事件
        /// </summary>
        private List<RawEvent> FilterNewEvents(List<RawEvent> rawEvents)
        {
            var newEvents = new List<RawEvent>();
            
            foreach (var rawEvent in rawEvents)
            {
                // 检查是否是重复事件
                if (!recentEventIds.Contains(rawEvent.id))
                {
                    newEvents.Add(rawEvent);
                }
            }
            
            return newEvents;
        }
        
        /// <summary>
        /// 限制注意力带宽
        /// </summary>
        private List<RawEvent> LimitAttentionBandwidth(List<RawEvent> events)
        {
            if (events.Count <= attentionBandwidth)
                return events;
            
            // 按距离和重要性排序
            var sortedEvents = events
                .Select(e => new {
                    Event = e,
                    Distance = Vector3.Distance(transform.position, e.location),
                    Priority = CalculateEventPriority(e)
                })
                .OrderBy(x => x.Distance)
                .ThenByDescending(x => x.Priority)
                .Take(attentionBandwidth)
                .Select(x => x.Event)
                .ToList();
            
            return sortedEvents;
        }
        
        /// <summary>
        /// 计算事件优先级
        /// </summary>
        private float CalculateEventPriority(RawEvent rawEvent)
        {
            float priority = 1f;
            
            // 基于事件类型
            switch (rawEvent.type)
            {
                case EventType.Conversation:
                    priority += 2f;
                    break;
                case EventType.Interaction:
                    priority += 1.5f;
                    break;
                case EventType.Movement:
                    priority += 0.5f;
                    break;
            }
            
            // 基于涉及的智能体
            if (rawEvent.metadata.ContainsKey("participants"))
            {
                var participants = rawEvent.metadata["participants"] as List<string>;
                if (participants != null && participants.Count > 1)
                {
                    priority += 1f; // 多人事件更重要
                }
            }
            
            return priority;
        }
        
        /// <summary>
        /// 处理事件列表
        /// </summary>
        private List<AgentEvent> ProcessEvents(List<RawEvent> rawEvents)
        {
            var processedEvents = new List<AgentEvent>();
            
            foreach (var rawEvent in rawEvents)
            {
                try
                {
                    var agentEvent = processor.ProcessRawEvent(rawEvent, embeddingEngine, languageModel);
                    if (agentEvent != null)
                    {
                        processedEvents.Add(agentEvent);
                        OnEventPerceived?.Invoke(agentEvent);
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogWarning($"[PerceptionSystem] Failed to process event {rawEvent.id}: {ex.Message}");
                }
            }
            
            return processedEvents;
        }
        
        /// <summary>
        /// 存储事件到记忆系统
        /// </summary>
        private void StoreEventsToMemory(List<AgentEvent> events)
        {
            if (memorySystem == null) return;
            
            foreach (var agentEvent in events)
            {
                try
                {
                    memorySystem.StoreEvent(agentEvent);
                }
                catch (Exception ex)
                {
                    Debug.LogWarning($"[PerceptionSystem] Failed to store event {agentEvent.eventId}: {ex.Message}");
                }
            }
        }
        
        /// <summary>
        /// 更新感知状态
        /// </summary>
        private void UpdatePerceptionState(List<AgentEvent> events)
        {
            foreach (var agentEvent in events)
            {
                recentEventIds.Add(agentEvent.eventId);
                eventTimeStamps[agentEvent.eventId] = agentEvent.timestamp;
            }
            
            currentPerceptions.Clear();
            currentPerceptions.AddRange(events);
        }
        
        /// <summary>
        /// 清理过期事件
        /// </summary>
        private void CleanupExpiredEvents()
        {
            var cutoffTime = DateTime.Now.AddSeconds(-eventRetentionTime);
            var expiredEvents = eventTimeStamps
                .Where(kv => kv.Value < cutoffTime)
                .Select(kv => kv.Key)
                .ToList();
            
            foreach (var eventId in expiredEvents)
            {
                recentEventIds.Remove(eventId);
                eventTimeStamps.Remove(eventId);
            }
        }
        
        /// <summary>
        /// 开始感知循环
        /// </summary>
        private void StartPerceptionLoop()
        {
            lastPerceptionTime = Time.time;
            
            if (enablePerceptionLogging)
            {
                Debug.Log($"[PerceptionSystem] Started perception loop with interval {perceptionInterval}s");
            }
        }
        
        /// <summary>
        /// 手动触发感知
        /// </summary>
        public List<AgentEvent> TriggerPerception()
        {
            return PerformPerceptionCycle();
        }
        
        /// <summary>
        /// 获取当前感知到的事件
        /// </summary>
        public List<AgentEvent> GetCurrentPerceptions()
        {
            return new List<AgentEvent>(currentPerceptions);
        }
        
        /// <summary>
        /// 设置感知参数
        /// </summary>
        public void SetPerceptionParameters(float newVisionRadius, int newAttentionBandwidth, float newInterval)
        {
            visionRadius = newVisionRadius;
            attentionBandwidth = newAttentionBandwidth;
            perceptionInterval = newInterval;
            
            if (enablePerceptionLogging)
            {
                Debug.Log($"[PerceptionSystem] Updated parameters: vision={visionRadius}, attention={attentionBandwidth}, interval={perceptionInterval}");
            }
        }
        
        /// <summary>
        /// 获取感知统计信息
        /// </summary>
        public string GetPerceptionStats()
        {
            return $"Recent Events: {recentEventIds.Count}, Current Perceptions: {currentPerceptions.Count}, Vision Radius: {visionRadius}";
        }
        
        /// <summary>
        /// 绘制感知范围（用于调试）
        /// </summary>
        private void OnDrawGizmosSelected()
        {
            if (!enableDebugVisualization) return;
            
            // 绘制感知范围
            Gizmos.color = Color.yellow;
            Gizmos.DrawWireSphere(transform.position, visionRadius);
            
            // 绘制当前感知到的事件位置
            Gizmos.color = Color.red;
            foreach (var perception in currentPerceptions)
            {
                Gizmos.DrawWireCube(perception.location, Vector3.one * 0.5f);
            }
        }
        
        /// <summary>
        /// 暂停感知系统
        /// </summary>
        public void PausePerception()
        {
            enabled = false;
        }
        
        /// <summary>
        /// 恢复感知系统
        /// </summary>
        public void ResumePerception()
        {
            enabled = true;
            lastPerceptionTime = Time.time;
        }
        
        /// <summary>
        /// 重置感知状态
        /// </summary>
        public void ResetPerceptionState()
        {
            recentEventIds.Clear();
            eventTimeStamps.Clear();
            currentPerceptions.Clear();
            lastPerceptionTime = Time.time;
        }
    }
}